#include "Bsp.h"

volatile int32_t ITM_RxBuffer;

void BSP_SystemClock_Config(void)
{
    LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);

    #if RCC_HSE_Enable
        LL_RCC_HSE_Enable();
        while(LL_RCC_HSE_IsReady() != 1);   //等待HSE就绪
        LL_RCC_HSE_EnableCSS();             //开启时钟保护
        LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_9);  //PLL时钟 = HSE / 1 * 9 = 72MHz
    #else
        LL_RCC_HSI_SetCalibTrimming(16);    //HSI校准, 默认8MHz
        LL_RCC_HSI_Enable();                //HSI使能
        while (LL_RCC_HSI_IsReady() != 1);
        LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_16);  //PLL时钟 = HSI / 2 * 16 = 64MHz
    #endif  /* RCC_HSE_Enable */
    
    LL_RCC_PLL_Enable();
    while (LL_RCC_PLL_IsReady() != 1);

    LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
    while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL);
}

void BSP_SysTick_Init(uint32_t Ticks)
{
    SysTick->LOAD  = (uint32_t)(Ticks - 1UL);                   /* 设置重装值 */
    SysTick->VAL   = 0UL;                                       /* 清除计数值 */
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                     SysTick_CTRL_ENABLE_Msk;                   /* 启用Systick */
}

void BSP_GPIO_Init(void)
{
    LL_GPIO_InitTypeDef GPIO_InitStruct;
    
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);

    GPIO_InitStruct.Pin        = LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15;
    GPIO_InitStruct.Mode       = LL_GPIO_MODE_OUTPUT;
    GPIO_InitStruct.Speed      = LL_GPIO_SPEED_FREQ_MEDIUM;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void BSP_WDT_Init(void)
{
    LL_IWDG_EnableWriteAccess(IWDG);
    LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_64);   // 40KHz / 64
    LL_IWDG_SetReloadCounter(IWDG, 625);  // 递减, 12bit 最大0xFFF
    LL_IWDG_DisableWriteAccess(IWDG);
}

/* BSP 初始化 ===========================================================*/
void BSP_init(void)
{
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);  //使能 IO复用时钟
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);   //使能 电源时钟

    // 调试IO使能
    LL_GPIO_AF_Remap_SWJ_NOJTAG();

    NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
    
    // 时钟初始化
    BSP_SystemClock_Config();
    SystemCoreClockUpdate();
    
    // GPIO初始化
    BSP_GPIO_Init();
    
    // WDT 初始化
    BSP_WDT_Init();
}

void BSP_Startup(void)
{
    // Systick 初始化
    BSP_SysTick_Init(SystemCoreClock / BSP_TICKS_PER_SEC);
    NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
    
    // 启动看门狗
    // if ((LL_PWR_IsActiveFlag_SB() == 0) || LL_RCC_IsActiveFlag_IWDGRST() == 0)
    // {
    //     LL_IWDG_Enable(IWDG);
    // }
    // else
    // {
    //     // 设置待机标志，立即进入待机处理
    // }
    
    LL_PWR_ClearFlag_SB();
    LL_PWR_ClearFlag_WU();
    LL_RCC_ClearResetFlags();
    
    // 启动Systick定时器
    Bsp_SysTick_Start();
}

void BSP_TickDelay(uint32_t Delay)
{
    __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */

    ((void)tmp);

    while (Delay)
    {
        if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
        {
            Delay--;
        }
    }
}

int fputc(int ch, FILE *f)
{
    return ITM_SendChar(ch);
}

int fgetc(FILE *f)
{
    return ITM_ReceiveChar();
}
